﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#include "GnufBindToFamilyParamDlg.h"
#include "IFamilyManager.h"
#include "IParameter.h"
#include "IUserTransaction.h"
#include "ParaDefineDlg.h"
#include "ParameterType.h"
#include <QPushButton>
#include "UiDocumentViewUtils.h"
#include "IElementBasicInformation.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace gfam;

GnufBindToFamilyParamDlg::GnufBindToFamilyParamDlg(QWidget *pParent) : QDialog(pParent)
{
    ui.setupUi(this);
    DBG_WARN_AND_RETURN_VOID_UNLESS(ui.buttonBox, L"ui.buttonBox is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(ui.buttonBox->button(QDialogButtonBox::Ok), L"button(QDialogButtonBox::Ok) is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(ui.buttonBox->button(QDialogButtonBox::Cancel), L"button(QDialogButtonBox::Cancel) is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(ui.buttonBox->button(QDialogButtonBox::Reset), L"button(QDialogButtonBox::Reset) is null.", L"paramodel", L"2024-02-20");
    ui.buttonBox->button(QDialogButtonBox::Ok)->setText(QString::fromStdWString(GBMP_TR(L"确定")));
    ui.buttonBox->button(QDialogButtonBox::Cancel)->setText(QString::fromStdWString(GBMP_TR(L"取消")));
    ui.buttonBox->button(QDialogButtonBox::Reset)->setText(QString::fromStdWString(GBMP_TR(L"新建参数")));
    connect(ui.buttonBox->button(QDialogButtonBox::Reset),SIGNAL(clicked()),this,SLOT(CreateNewParam()));
    m_pFamManager = nullptr;
    m_curParam = nullptr;
    m_bindParamDefId = -1;
}

GnufBindToFamilyParamDlg::~GnufBindToFamilyParamDlg()
{

}

void GnufBindToFamilyParamDlg::InitDialog(const IParameter* curParam, Int32 bindParamDefId,
    gfam::IFamilyManager* pFamManager)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(curParam, L"param is null.", L"paramodel", L"2024-02-20");
    m_pFamManager = pFamManager;
    m_curParam = curParam;
    m_bindParamDefId = bindParamDefId;
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamManager != nullptr, L"pFamManager为空", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(curParam->GetParameterDefinition() != nullptr, L"curParam->GetParameterDefinition()为空", L"paramodel", L"2024-02-20");
    ui.label_ParamName->setText(QString::fromStdWString(curParam->GetParameterDefinition()->GetName()));
    ui.label_ParamType->setText(GetParameterTypeName(curParam));
    InitParamList(curParam, bindParamDefId, pFamManager);
}

QString GnufBindToFamilyParamDlg::GetParameterTypeName(const IParameter* curParam)
{
    DBG_WARN_AND_RETURN_UNLESS(curParam, QString::fromStdWString(L""), L"param is null.", 
        L"paramodel", L"2024-02-20");

    std::wstring strParamType;
    DBG_WARN_AND_RETURN_UNLESS(curParam->GetParameterDefinition() != nullptr, QString::fromStdWString(L""), L"curParam->GetParameterDefinition()为空", L"paramodel", L"2024-02-20");
    UniIdentity ptId = curParam->GetParameterDefinition()->GetParameterTypeId();
    if (ptId == PARAMETER_TYPE(Angle))
    {
        strParamType = GBMP_TR(L"角度");
    }
    else if (ptId == PARAMETER_TYPE(Length))
    {
        strParamType = GBMP_TR(L"长度");
    }
    else if (ptId == PARAMETER_TYPE(Material))
    {
        strParamType = GBMP_TR(L"材质");
    }
    else if (ptId == PARAMETER_TYPE(Number))
    {
        strParamType = GBMP_TR(L"整型");
    }
    else if (ptId == PARAMETER_TYPE(Float))
    {
        strParamType = GBMP_TR(L"数值");
    }
    return QString::fromStdWString(strParamType);
}

gfam::FamilyParameterType GnufBindToFamilyParamDlg::GetFamilyparameterType(const gcmp::IParameter * curParam)
{
    DBG_WARN_AND_RETURN_UNLESS(curParam, gfam::FamilyParameterType::Invalid, L"curParam is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_UNLESS(curParam->GetParameterDefinition(), gfam::FamilyParameterType::Invalid, L"curParam->GetParameterDefinition() is null.", L"paramodel", L"2024-02-20");

    gfam::FamilyParameterType famParamType = gfam::FamilyParameterType::Length;
    UniIdentity ptId = curParam->GetParameterDefinition()->GetParameterTypeId();
    if (ptId == PARAMETER_TYPE(Angle))
    {
        famParamType = gfam::FamilyParameterType::Angle;
    }
    else if (ptId == PARAMETER_TYPE(Length))
    {
        famParamType = gfam::FamilyParameterType::Length;
    }
    else if (ptId == PARAMETER_TYPE(Material))
    {
        famParamType = gfam::FamilyParameterType::Material;
    }
    else if (ptId == PARAMETER_TYPE(Number))
    {
        famParamType = gfam::FamilyParameterType::Integer;
    }
    else if (ptId == PARAMETER_TYPE(YesNo))
    {
        famParamType = gfam::FamilyParameterType::Bool;
    }
    else if (ptId == PARAMETER_TYPE(Float))
    {
        famParamType = gfam::FamilyParameterType::Double;
     }
    else if (ptId == PARAMETER_TYPE(Text))
    {
        famParamType = gfam::FamilyParameterType::String;
    }
    else if (ptId == PARAMETER_TYPE(TextStyle))
    {
        famParamType = gfam::FamilyParameterType::TextStyle;
    }
    return famParamType;
}

void GnufBindToFamilyParamDlg::InitParamList(const IParameter* curParam, Int32 bindParamDefId,gfam::IFamilyManager* pFamManager)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(curParam, L"curParam is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamManager, L"m_pFamManager is null.", L"paramodel", L"2024-02-20");

    const IParameterDefinition* curParamDef = curParam->GetParameterDefinition();
    std::vector<ElementId> allParams = m_pFamManager->GetFamilyParameterDefinitionIds();
    ui.listWidget_FamParams->clear();
    ui.listWidget_FamParams->blockSignals(true);
    OwnerPtr<QListWidgetItem> opItem = NEW_AS_OWNER_PTR(QListWidgetItem, ui.listWidget_FamParams);
    opItem->setText(QString::fromStdWString(GBMP_TR(L"<无>")));
    opItem->setData(Qt::UserRole, -1);
    ui.listWidget_FamParams->addItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
    int curBindindex = 0;
    FOR_EACH(idParam, allParams)
    {
        const IFamilyParameterDefinition *pParamDef = m_pFamManager->GetFamilyParameterDefinition(idParam);
        if (pParamDef != nullptr
            && pParamDef->GetParameterTypeId() == curParamDef->GetParameterTypeId()
            && pParamDef->GetStorageType() == (ParameterStorageType)curParamDef->GetStorageType()
            && pParamDef->GetUnitTypeId() == curParamDef->GetUnitTypeId())
        {
            Int32 paramDefId = m_pFamManager->GetFamilyParameterDefinitionId(pParamDef->GetElementId());
            OwnerPtr<QListWidgetItem> opItem = NEW_AS_OWNER_PTR(QListWidgetItem, ui.listWidget_FamParams);
            DBG_WARN_AND_RETURN_VOID_UNLESS(opItem, L"opItem is null.", L"paramodel", L"2024-02-20");
            DBG_WARN_AND_RETURN_VOID_UNLESS(pParamDef->GetBasicInformation(), L"pParamDef->GetBasicInformation() is null.", L"paramodel", L"2024-02-20");
            opItem->setText(QString::fromStdWString(pParamDef->GetBasicInformation()->GetName()));
            opItem->setData(Qt::UserRole, paramDefId);
            ui.listWidget_FamParams->addItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
            if (paramDefId == bindParamDefId)
            {
                curBindindex = ui.listWidget_FamParams->count() - 1;
            }
        }
    }
    ui.listWidget_FamParams->setCurrentRow(curBindindex);
    ui.listWidget_FamParams->blockSignals(false);
}

Int32 GnufBindToFamilyParamDlg::GetBoundParamDefId()
{
    if(ui.listWidget_FamParams->currentRow() == 0)
    {
        return -1;
    }

    if (ui.listWidget_FamParams->currentItem())
    {
        return ui.listWidget_FamParams->currentItem()->data(Qt::UserRole).toInt();
    }

    return -1;
}

void GnufBindToFamilyParamDlg::CreateNewParam()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamManager, L"m_pFamManager is null.", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_curParam, L"m_curParam is null.", L"paramodel", L"2024-02-20");

    gcmp::OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pFamManager->GetDocument(), (GBMP_TR(L"增加族参数")));
    gfam::FamilyParameterType itype = gfam::FamilyParameterType::Length;
    itype = GetFamilyparameterType(m_curParam); 
    ParaDefineDlg paradlg(itype, false);
    paradlg.SetFamilyManager(m_pFamManager);
    if (paradlg.exec() == QDialog::Accepted)
    {
        ut->Commit();
        InitParamList(m_curParam,m_bindParamDefId,m_pFamManager);
        return;
    }
    ut->Rollback();
    //事务回退会造成m_pFamManager指针不稳定，需重新获取一下。
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    m_pFamManager = IFamilyManager::Get(pDoc);
}